package grame

import grails.util.Metadata
import org.apache.log4j.Level
import org.apache.log4j.LogManager
import org.apache.log4j.Logger

/**
 * @auth shining wang (shiningwang@vshining.com)
 */
class Log4jGrameUtil {
    private static Properties prop
    private static final String USER_DIR = System.getProperty("user.dir")
    private static final String APP_NAME = Metadata.getCurrent().getApplicationName()
    private static File LCFG_FILE = new File("${USER_DIR}/${APP_NAME}_lcfg")
    private static long lastModified = 0

    static void init() {
        println "Try to update logger level from GRAME LOGGER LEVEL config file '${LCFG_FILE}'"
        if (prop == null)
            prop = new Properties()
        // init logger from config file
        if (LCFG_FILE.exists()) {
            InputStream inputStream
            try {
                if (LCFG_FILE.lastModified() > lastModified) {
                    lastModified = LCFG_FILE.lastModified()
                    println "Reload GRAME LOGGER LEVEL config file '${LCFG_FILE}"
                    Properties _prop = new Properties()
                    synchronized (_prop) {
                        inputStream = new FileInputStream(LCFG_FILE)
                        prop.load(inputStream)
                    }
                }
                prop.stringPropertyNames().each { logger ->
                    setLoggerLevel(logger, prop.getProperty(logger))
                }
            } catch (FileNotFoundException ignore) {
                if (isDebug()) {
                    println "GRAME LOGGER LEVEL config file '${LCFG_FILE}' not found"
                }
            } catch (IOException e) {
                new RuntimeException("Load GRAME LOGGER LEVEL config file '${LCFG_FILE} failed", e).printStackTrace()
            } finally {
                if (inputStream)
                    inputStream.close()
            }
        } else {
            if (isDebug()) {
                println "GRAME LOGGER LEVEL config file '${LCFG_FILE}' not exist"
            }
        }
    }

    static setLoggerLevel(String logger, String level) {
        Logger _logger = LogManager.getLogger(logger)
        if (_logger) {
            _logger.setLevel(Level.toLevel(level, Level.INFO))
            prop.setProperty(_logger.getName(), _logger.getLevel().toString())
            if (isDebug()) {
                println "Logger '${_logger.getName()}' has been updated to '${_logger.getLevel().toString()}'"
            }
        }
    }

    static synchronized store() {
        OutputStream outputStream
        try {
            if (System.currentTimeMillis() - LCFG_FILE.lastModified() < 1001) {
                return
            }
            outputStream = new FileOutputStream(LCFG_FILE)
            prop.store(outputStream, "GRAME LOGGER LEVEL CONFIGURATION")
            if (isDebug()) {
                println "GRAME LOGGER LEVEL config has been stored to file '${LCFG_FILE}'"
            }
        } catch (IOException e) {
            new RuntimeException("Store GRAME LOGGER LEVEL config file '${LCFG_FILE} failed", e).printStackTrace()
        } finally {
            if (outputStream)
                outputStream.close()
        }
    }

    private static boolean isDebug() {
        return LogManager.getLogger("grame").isDebugEnabled()
    }
}
